package Server;

/**
 *
 * @author Daniel
 */
import java.net.*;
import java.io.*;
import java.util.*;

public class Client implements Runnable
{
    private Socket connection;
    private Thread clientThread;
    private OutputStream outStream;
    private InputStream inStream;
    String message=null;
    private int loginStatus=0;

    
    public Client(Socket connection, int id)
    {
        //Construct our we client handler
        this.connection     = connection;
        this.clientThread   = new Thread(this, "" + id);
        try
        {
            this.outStream      = new BufferedOutputStream(this.connection.getOutputStream());
            this.inStream = new BufferedInputStream((this.connection.getInputStream()));

            System.out.println("Connection request received");
            //Make first contact
            this.initConn();
            //Wait for message and respond
            //Handle the sh*t out of this mofo.
            System.out.println("Client thread started. You are thread "+ this.clientThread.getId() );
        }
        catch(IOException ioe)
        {
            System.out.println("IO exception while attempting to setup outputstream");
            System.out.println("Error: " + ioe);
            System.exit(3);
        }          
        this.clientThread.start();

    }
    
    public void run()
    {

        String outMessage = "Got it";
        byte [] buff = new byte[500];
        int messageLength=0;

        //keep accepting input
        while(true){
            try {
                //read input message
                inStream = this.connection.getInputStream();
                messageLength = inStream.read(buff);
                message = new String(buff,0,messageLength);
                //display message
                System.out.println("Client Request: \n\t"+message);
                processMessage(message);

            } catch (SocketException se){
                this.clientThread.stop();
                this.clientThread.destroy();
                System.out.println("Client Disconnected. Stopping Thread...");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void processMessage(String message) throws IOException {

        //get Process Letter
        char process = message.charAt(2);
        //System.out.println(process);
        //message = message.replace('|',' ');

        //login
        if(process == 'L'){
           int spaces = 0;
           int newId=0;
           String id="";
           char current;
           String name = "";
           //System.out.println(message);
           for(int i=0;i<message.length();i++){

              current = message.charAt(i);
               //need this to count how many spaces have spotted
               if(current=='|'){
                   spaces++;
               }
               //after second space id starts
               else if(spaces == 2){
                    id+=current;
               }
               //after 3rd space name starts. 4th space included because there is space between fname and sname
               if(spaces == 3){
                   name+=current;
               }
           }
            //convert id from string to int
           newId = Integer.parseInt(id);
            //set letter char to 0
           process = 0;

            //check if customer exists
           checkCustomer(newId,name);
        }
        //search
        else if(process =='S'){
            int spaces = 0;
            String criteria = "";
            char type = message.charAt(4);
            char current;
            //System.out.println(message);
            for(int i=0;i<message.length();i++){

                current = message.charAt(i);

                if(current=='|'){
                    spaces++;
                }
                if(spaces == 3){
                    criteria+=current;
                }
            }

            if(type == 'A'){
                 boolean found = false;
                String currBook="";
                //again the stupid space at the start
                criteria = criteria.substring(1,criteria.length());

                //if regex used would be better, now you have to enter author name exactly as it is in in the file
                for(BookRec book:Server.bsd.getBooks()){
                    if(book.getAuthor().equals(criteria)){
                        found = true;
                        currBook = book.toString();
                    }
                }

                if(found){
                    lookingForBook(currBook);
                }
            }
            else if(type=='T'){

            }
            else if (type=='I'){

            }
            else if(type =='C'){

            }
            else if(type=='Y'){

            }
            else if(type=='P'){

            }
        }
        //register
        else if(process == 'R'){

            String name = "",surname="",address="";
            int spaces = 0;
            char curr =0;
            boolean inserted = false;

            for(int i=0;i<message.length();i++){
               curr = message.charAt(i);

                if(curr=='|'){
                    spaces++;
                }

                if(spaces == 2){
                    name+=curr;
                }
                if(spaces == 3){
                    surname+=curr;
                }
                if(spaces == 4){
                    address+=curr;
                }
            }
            //remove the first char of each variable
            name = name.substring(1,name.length());
            surname = surname.substring(1,surname.length());
            address = address.substring(1,address.length());

            //build name string
            name = name+" "+surname;

            Server.bsd.addCust(1, name, address);

            for(CustRec customer:Server.bsd.getCusts()){
                if(customer.getName().equals(name)){
                    inserted=true;
                }
            }
            message="";
            if(inserted){

                message += loginStatus+"|RR|T";
            }
            else{
                message += loginStatus+"|RR|F";
            }

            writeMessage(message);

        }
        else if (process == 'B'){
            //System.out.println(message);
             char curr;
            int spaces=0;
            String bookId = "";
            String custId="";
            String price="";
            for(int i=0;i<message.length();i++){
               curr = message.charAt(i);

                if(curr=='|'){
                    spaces++;
                }

                if(spaces == 2){
                    bookId+=curr;
                }
                else if(spaces == 3){
                    custId+=curr;
                }
                else if(spaces == 4){
                    price+=curr;
                }
            }
            bookId = bookId.substring(1,bookId.length());
            custId = custId.substring(1,custId.length());
            price = price.substring(1,price.length());

            int newBookId = Integer.parseInt(bookId);
            int newCustId = Integer.parseInt(custId);

            Server.bsd.addOrder(newBookId,newCustId,price,Server.bsd.getDate(),"To Be Dispatched","ToHandle");
            //System.out.println(bookId+" "+ custId+" "+price+" "+Server.bsd.getDate());

            writeMessage(loginStatus+"|BR|T|%");
        }
    }
    private void lookingForBook(String book){
        String newBook=loginStatus+"|SR|";

        int bSpaces=0;

        for(int i=0;i<book.length();i++)
        {
            //get character from the string
            char bCurr = book.charAt(i);

            //if its a space increment
            if(bCurr=='|'){
                bSpaces++;
            }

            //on the second space add bar (increment the bSpaces so this if will never get accessed again)
            if(bSpaces == 2){
                bCurr='|';
                bSpaces++;
            }
            //
            if(bCurr =='\t'){
                newBook+='|';
            }
            else{
                newBook+=bCurr;
            }
        }
        newBook = newBook.substring(0,newBook.length()-1);
        newBook+="|%";
        //System.out.println(newBook);
        writeMessage(newBook);
    }
    //check if customer exists in the array
    private void checkCustomer(int id, String name){

        String outMessage = "";
        boolean found = false;
        //for some reason there is a space at the start of the name, so this removes it
        name = name.substring(1,name.length());
        //loop through all customers
        for(CustRec customer : Server.bsd.getCusts()){

            //check if values match and set flags
            if(customer.getName().equals(name) && customer.getCustID() == id){
                loginStatus=1;
                found = true;
            }
        }
        //YES! Found it
        if(found){
            outMessage += loginStatus+"|LR|T|%";
        }
        //No such user
        else{
            outMessage += loginStatus+"|LR|F|%";
        }

        //send back the reply
        writeMessage(outMessage);
    }
    
    public Socket getSocket(){
        return this.connection;
    }

    private boolean writeMessage(String message)
    {
        try
        {
            System.out.println("Server Response:\n\t"+message);
            outStream = this.connection.getOutputStream();
            outStream.write(message.getBytes());
        }
        catch(IOException ioe)
        {
            System.out.println("IOException when trying to write message");
            System.out.println("IOE from thread/client: " + this.clientThread.getId());
            System.out.println("Error: " + ioe);
            return false;
        }
        return true;
    }

    private void initConn()
    {
        //Send client it's ID and confirm connection
        this.writeMessage("Y");
    }

}